package com.eoekun.dashboard.contoller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.eoekun.dashboard.dao.dataobject.ProjectParam;
import com.eoekun.dashboard.dao.dataobject.ProjectParamExample;
import com.eoekun.dashboard.dao.mapper.ProjectParamMapperExt;
import com.eoekun.dashboard.model.PageVO;
import com.eoekun.dashboard.model.Result;
import com.eoekun.dashboard.model.ResultCode;
import com.eoekun.dashboard.model.enums.ParamTypeEnum;
import com.eoekun.dashboard.model.vo.KeyValueVO;

@RestController
@RequestMapping("/param/")
public class ParamController {

    private static final Logger log = LoggerFactory.getLogger(ParamController.class);
    @Resource
    private ProjectParamMapperExt paramMapperExt;

    private static final List<ProjectParam> PARAM_CACHE = new ArrayList<>();

    @RequestMapping("load")
    public Result<Map<Integer, List<KeyValueVO>>> load() {
        Map<Integer, List<KeyValueVO>> map = new HashMap<>();
        List<ProjectParam> params = paramsLoad(false);
        if (params.isEmpty()) {
            return new Result<>(map);
        }
        for (ProjectParam param : params) {
            Integer paramType = param.getParamType();
            List<KeyValueVO> list = null;
            if (map.containsKey(paramType)) {
                list = map.get(paramType);
            } else {
                list = new ArrayList<>();
                map.put(paramType, list);
            }
            list.add(new KeyValueVO(param.getValue(), param.getName()));
        }
        log.info("全局参数返回:{}", map);
        return new Result<>(map);

    }

    @RequestMapping("loadParam")
    public Result<List<KeyValueVO>> loadParam(Integer paramType) {
        List<KeyValueVO> list = new ArrayList<>();
        ProjectParamExample example = new ProjectParamExample();
        if (null == paramType) {
            example.createCriteria();
        } else {
            example.createCriteria().andParamTypeEqualTo(paramType);
        }
        List<ProjectParam> allParamRecord = paramsLoad(false);
        List<ProjectParam> params = filterByParamType(allParamRecord, paramType);
        if (params.isEmpty()) {
            return new Result<>(list);
        }
        for (ProjectParam param : params) {
            if (null == paramType) {
                list.add(new KeyValueVO(param.getValue(), param.getName()));
            } else {
                list.add(new KeyValueVO(param.getName()));
            }
        }
        log.info("参数{}返回:{}", paramType, list);
        return new Result<>(list);
    }

    @PostConstruct
    public void paramInit() {
        log.info("系统参数初始化....");
        paramsLoad(true);
    }

    @GetMapping("params")
    public Result<PageVO<ProjectParam>> paramsLoad(Boolean forceUpdate, Integer paramType,
            Integer page, Integer limit) {
        if (!Boolean.TRUE.equals(forceUpdate)) {

        } else {
            paramReload();
        }
        ProjectParamExample example = new ProjectParamExample();
        example.setPageNo(page);
        example.setPageSize(limit);
        if (null == paramType) {
            example.createCriteria();
        } else {
            example.createCriteria().andParamTypeEqualTo(paramType);
        }
        List<ProjectParam> data = paramMapperExt.selectByExample(example);
        Long total = paramMapperExt.countByExample(example);
        PageVO<ProjectParam> pageVO = new PageVO<>(data, total);
        return new Result<>(pageVO);
    }

    @PostMapping("params")
    public Result<Void> paramsAdd(@RequestBody ProjectParam param) {
        param.setId(null);
        param.setIsDeleted(0);
        paramMapperExt.insertSelective(param);
        paramReload();
        return Result.ofSuccess();
    }

    @PutMapping("params/{id}")
    public Result<Void> paramsUpdate(@PathVariable Long id, @RequestBody ProjectParam param) {
        boolean allowUpdate = checkAllowUpdate(id);
        if (!allowUpdate) {
            return new Result<Void>(ResultCode.NOT_SUPPORT_OPERATION, "系统参数不允许操作");
        }
        if (null != param.getId()) {
            paramMapperExt.updateByPrimaryKeySelective(param);
            paramReload();
        }
        return Result.ofSuccess();
    }

    @DeleteMapping("params/{id}")
    public Result<Void> paramsDelete(@PathVariable Long id) {
        boolean allowUpdate = checkAllowUpdate(id);
        if (!allowUpdate) {
            return new Result<Void>(ResultCode.NOT_SUPPORT_OPERATION, "系统参数不允许操作");
        }
        if (null != id) {
            paramMapperExt.deleteByPrimaryKey(id);
            paramReload();
        }
        return Result.ofSuccess();
    }

    private void paramReload() {
        log.info("系统参数重新加载....");
        paramsLoad(true);
    }

    private List<ProjectParam> paramsLoad(Boolean forceUpdate) {
        if (!Boolean.TRUE.equals(forceUpdate)) {
            // 缓存参数
        } else {
            PARAM_CACHE.clear();
            List<ProjectParam> params = selectAll();
            for (ProjectParam projectParam : params) {
                PARAM_CACHE.add(projectParam);
            }
        }
        return PARAM_CACHE;
    }

    private List<ProjectParam> selectAll() {
        ProjectParamExample example = new ProjectParamExample();
        example.createCriteria();
        List<ProjectParam> params = paramMapperExt.selectByExample(example);
        return params;
    }

    private boolean checkAllowUpdate(Long id) {
        ProjectParam record = paramMapperExt.selectByPrimaryKey(id);
        if (null != record) {
            Integer paramType = record.getParamType();
            if (ParamTypeEnum.参数类型.getValue().equals(paramType)) {
                return false;
            }
        }
        return true;
    }

    private static List<ProjectParam> filterByParamType(List<ProjectParam> allParamRecord,
            Integer paramType) {
        if (null == paramType) {
            return allParamRecord;
        }
        List<ProjectParam> params = new ArrayList<>();
        if (null != paramType) {
            for (ProjectParam record : allParamRecord) {
                if (record.getParamType().equals(paramType)) {
                    params.add(record);
                }
            }
        }
        return params;
    }
}
